﻿#define  _CRT_SECURE_NO_WARNINGS  1
#include <stdio.h>
//结构体（自定义的数据类型）:用来描述一些复杂的对象：比如说：一个人，一所学校
//结构的声明
//struct stu
//{
//	char name[20];
//	int age;
//	float score;
//}s4,s5,s6;//全局变量，一般不这样写
//struct B
//{
//	char ch;
//	int n;
//};
//struct stu
//{	
//	char name[20];
//	int age;
//	struct B bb;
//	float score;
//};
//struct stu s6;//全局变量
//int main()
//{
//	////结构体变量的定义
//	//struct stu s1;//局部变量
//	//struct stu s2;
//	//struct stu s3;
//	//结构体变量的初始化
//	struct stu s1 = { "张三",18,{'q',100},95.5f};
//	struct stu s2 = {.age=18,.name="张三",.score=95.5f,.bb={'q',100}};
//	//struct stu s2 = { .age = 18,.name = "张三",.score = 95.5f,.bb.ch='q',.bb.n=100};
//	printf("%s\n", s1.name);
//	printf("%d\n", s1.age);
//	printf("%c\n", s1.bb.ch);
//	printf("%d\n", s1.bb.n);
//	printf("%lf\n", s1.score);
//	printf("%d %s %lf %c %d\n", s2.age, s2.name, s2.score, s2.bb.ch, s2.bb.n);
//	return 0;
//}

//移位操作符   移位操作符的操作数只能是整数
//左移操作符
//int main()
//{
//	int n = 12;
//	//00000000000000000000000000001100  12的补码
//	//左移操作符的规则:左边抛弃，右边补0
//	//00000000000000000000000000011000  //24
//	int m = n << 1;
//	printf("%d\n", n);
//	printf("%d\n", m);
//	return 0;
//}

//int main()
//{
//	int n = 12;
//	printf("%d\n", n);
//	n <<= 1;
//	printf("%d\n", n);
//	return 0;
//}

//
//int main()
//{
//	int a = -10;
//	//10000000 00000000 00000000 00001010  -10的原码
//	//11111111 11111111 11111111 11110101  -10的反码
//	//11111111 11111111 11111111 11110110  -10的补码
//	//11111111 11111111 11111111 11101100
//	//10000000 00000000 00000000 00010011
//	//10000000 00000000 00000000 00010100   //-20
//	int b = a << 1;
//	printf("%d\n", a);
//	printf("%d\n", b);
//	return 0;
//}


//右移操作符
//VS2022中使用的是算术右移:左边用原该值的符号位填充，右边丢弃
//int main()
//{
//	int a = -10;
//	//10000000 0000000 0000000 00001010
//	//11111111 1111111 1111111 11110101
//	//11111111 1111111 1111111 11110110   -10在内存中的补码
//	//11111111 1111111 1111111 11111011 
//	//10000000 0000000 0000000 00000100
//	//10000000 0000000 0000000 00000101   //-5
//	int b = a >> 1;
//	printf("%d\n", a);
//	printf("%d\n", b);
//	return 0;
//}


//位操作符:&、|、^、~
// &:按位与:对应的二进制位相与:有0则为0，两个同时为1才为1
//int main()
//{
//	int a = -5;//10000000 00000000 00000000 00000101
//	           //11111111 11111111 11111111 11111010
//	               //11111111 11111111 11111111 11111011  -5的补码
//	int b = 13;    //00000000 00000000 00000000 00001101  13的补码
//	int c = a & b; //00000000 00000000 00000000 00001001  //9
//	printf("%d\n", c);
//	return 0;
//}

//|:按位或:对应的二进制位或运算:有1则为1，两个同时为0才为0
//int main()
//{
//	int a = -5;     //11111111 11111111 11111111 11111011  -5的补码
//	int b = 13;     //00000000 00000000 00000000 00001101  13的补码
//	int c = a | b;  //11111111 11111111 11111111 11111111
//	                //10000000 00000000 00000000 00000000
//	                //10000000 00000000 00000000 00000001
//	printf("%d\n", c);
//	return 0;
//}

////^:按位异或:对应的二进制位异或运算:相同为0，相异为1
//int main()
//{
//	int a = -5;                    //11111111 11111111 11111111 11111011  -5的补码
//	int b = 13;                    //00000000 00000000 00000000 00001101  13的补码
//	int c = a ^ b;                 //11111111 11111111 11111111 11110110 
//	                               //10000000 00000000 00000000 00001001
//	                               //10000000 00000000 00000000 00001010  //-10
//	printf("%d\n", c);
//	return 0;
//}

//~:按位取反：把内存中存储的二进制位原来是1改为0，原来是0的改为1
//int main()
//{
//	int a = 0;           //00000000 00000000 00000000 00000000
//	printf("%d\n", ~a);  //11111111 11111111 11111111 11111111
//	                     //10000000 00000000 00000000 00000000
//	                     //10000000 00000000 00000000 00000001   //-1
//	return 0;
//}

//不能创建临时变量（第三个变量），实现两个整数的交换
//int main()//创建了临时变量的方法
//{
//	int a = 0;
//	int b = 0;
//	scanf("%d %d", &a,&b);
//	printf("交换前:a=%d,b=%d\n", a, b);
//	int c = a;
//	 a = b;
//	 b = c;
//	printf("交换后:a=%d,b=%d\n", a, b);
//	return 0;
//}

//int main()
//{
//	int a = 0;
//	int b = 0;
//	scanf("%d %d", &a, &b);//10 20
//	printf("交换前:a=%d,b=%d\n", a, b);
//	a = a + b;//30   a=a+b（这个表达式）如果a和b的数值太大，可能会存在溢出的可能性
//	b = a - b;//10
//	a = a - b;
//	printf("交换后:a=%d,b=%d\n", a, b);
//	return 0;
//}

////对于^按位异或操作符来说:  a^a=0  a^0=a
//int main()
//{
//	int a = 0;
//	int b = 0;
//	scanf("%d %d", &a, &b);
//	printf("交换前:a=%d,b=%d\n", a, b);
//	a = a^b;
//	b = a^b;//a^b^b
//	a = a ^ b;//a^b^a
//	printf("交换后:a=%d,b=%d\n", a, b);
//     return 0;
//}

//编写代码实现：求一个整数存储在内存中的二进制中1的个数。
//找到内存中的二进制序列
//对于十进制数字来说:123  想要得到123的每一位 123%10==3  123/10=12  12%10==2  12/10==1  1%10==1  1/10==0  
//对于二进制数字来说:13   想要得到13的每一位二进制序列  13%2==1  13/2==6  6%2==0  6/2==3  3%2==1  3/2==1  1%2==1  1/2==0      1101
//int main()
//{
//	int  n = 0;
//	int count = 0;
//	scanf("%d", &n);
//	while (n)
//	{
//		if (n % 2 == 1)	
//			count++;
//			n = n / 2;
//	}
//	printf("%d\n", count);
//	return 0;
//}

//int main() //试除法对负数是存在问题的
//{
//	int  n = -1;  //10000000 00000000 00000000 00000001
//	              //11111111 11111111 11111111 11111110
//	              //11111111 11111111 11111111 11111111   -1的补码
//	int count = 0;
//	//scanf("%d", &n);
//	while (n)
//	{
//		if (n % 2 == 1)
//			count++;
//		n = n / 2;
//	}
//	printf("%d\n", count);
//	return 0;
//}


//想要得到数字二进制位的最低位
//15    00000000 00000000 00000000 00001111
//1     00000000 00000000 00000000 00000001 
//15&1  00000000 00000000 00000000 00000001  换位与完后再将15右移一位
//int main()
//{
//	int  n = 15;
//	int count = 0;
//	for (int i = 0; i < 32; i++)
//	{
//		if ((n & 1) == 1)
//			count++;
//		n >>= 1;
//	}
//	printf("%d\n", count);
//	return 0;
//}


//int main()
//{
//	int  n = -1;
//	int count = 0;
//	for (int i = 0; i < 32; i++)
//	{
//		if ((n & 1) == 1)
//			count++;
//		n >>= 1;
//	}
//	printf("%d\n", count);
//	return 0;
//}


//n= n & (n-1)该表达式的意思是  让n的二进制序列最右边的1消失
//n=n &(n-1)       n   13   00000000000000000000000000001101      n    00000000000000000000000000001100    n     00000000000000000000000000001000
//               n-1   12   00000000000000000000000000001100     n-1   00000000000000000000000000001011   n-1    00000000000000000000000000000111
//                 13&12    00000000000000000000000000001100  n&(n-1)  00000000000000000000000000001000  n&(n-1) 00000000000000000000000000000000
//int main()
//{
//	int n = 0;
//	int count = 0;
//	scanf("%d", &n);
//	while (n)
//	{	
//		n = n & n - 1;
//		count++;
//	}
//	printf("%d\n", count);
//	return 0;
//}


////写一个代码，判断n是否是2的次方数
//int main()
//{
//	int  n = 0;
//	scanf("%d", &n);
//	if (( n & (n - 1)) == 0)
//		printf("%d是2的次方数\n", n);
//	else
//		printf("%d不是2的次方数\n", n);
//	return 0;
//}

//练习2：⼆进制位置0或者置1
//编写代码将13⼆进制序列的第5位修改为1，然后再改回0
//int main()
//{              //00000000 00000000 00000000 00011101  //29    00000000 00000000 00000000 00011101
//	int n = 13;  //00000000 00000000 00000000 00001101          11111111 11111111 11111111 11101111
//	            //00000000 00000000 00000000 00010000           00000000 00000000 00000000 00010000
//	            //00000000 00000000 00000000 00000001           00000000 00000000 00000000 00000001
//	n = n | (1 << 4); 
//	printf("%d\n", n);
//	n = n & (~(1 << 4));
//	printf("%d\n", n);
//	return 0;
//}


//逗号表达式
//int main()
//{
//	int a = 1;
//	int b = 2;
//	int c = (a > b, a = b + 10, a, b = a + 1);//表达式最右边是整个表达式的结果
//
//	printf("%d\n", c);
//	return 0;
//}
//
//int main()
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	printf("%d\n", arr[5]);
//	//[]下标引用操作符  操作数是arr和5
//	return 0;
//}



//void test()
//{
//
//}
//int main()
//{
//	printf("hehe");//()是函数调用操作符的 操作数是printf和 “hehe”
//	return 0;
//	test();  操作数是test
//}